<template>
    <div class="editor-container">
      <!-- 左侧音符菜单 -->
      <MakeScore @click-number="insertNoteSymbol" />
  
      <!-- 右侧编辑区域 -->
      <div class="editor-area">
        <!-- 工具栏 -->
        <div class="top-toolbar">
          <el-button-group>
            <el-button size="small" @click="undo" :disabled="state.historyIndex <= 0">撤销</el-button>
            <el-button size="small" @click="redo" :disabled="state.historyIndex >= state.history.length - 1">
              重做
            </el-button>
          </el-button-group>
  
          <el-button-group>
            <el-button size="small" @click="copySelection">复制</el-button>
            <el-button size="small" @click="pasteFromClipboard">粘贴</el-button>
          </el-button-group>
  
          <el-button size="small" @click="addLyricLine">添加歌词行</el-button>
          
          <!-- 对齐方式切换 -->
          <el-button-group>
            <el-button 
              size="small" 
              :type="alignMode === 'left' ? 'primary' : 'default'"
              @click="setAlignMode('left')"
              title="左对齐"
            >
              <i class="el-icon-align-left"></i> 左对齐
            </el-button>
            <el-button 
              size="small" 
              :type="alignMode === 'justify' ? 'primary' : 'default'"
              @click="setAlignMode('justify')"
              title="两端对齐"
            >
              <i class="el-icon-full-screen"></i> 两端对齐
            </el-button>
          </el-button-group>
          
          <div class="zoom-info">缩放: {{ zoom }}%</div>
  
          <el-button-group>
            <el-button size="small" @click="addNewPage">新增页</el-button>
            <el-button
              size="small"
              @click="removeCurrentPageIfEmpty"
              :disabled="currentLine.page === 0 || !isCurrentPageEmpty()"
            >
              删除空页
            </el-button>
          </el-button-group>
        </div>
  
        <!-- 可滚动的编辑容器 -->
        <div class="editor-scroll-container" @wheel="handleWheel" ref="scrollContainerRef">
          <div class="editor-zoom-container" :style="{ transform: `scale(${zoom / 100})` }">
            <!-- A4纸张页面 -->
            <div v-for="(page, pageIndex) in pages" :key="'page-' + pageIndex" class="page-container">
              <!-- 每一页的音符行循环 -->
              <div v-for="(line, lineIndex) in page.lines" :key="'line-' + pageIndex + '-' + lineIndex" class="line-container">
                <!-- 音符区域 -->
                <div
                  class="note-area"
                  :class="{
                    'active': isNoteAreaActive(pageIndex, lineIndex),
                    'no-text-input': true
                  }"
                  :data-page="pageIndex"
                  :data-line="lineIndex"
                  tabindex="0"
                  ref="noteAreas"
                  @focus="handleNoteFocus($event, pageIndex, lineIndex)"
                  @blur="handleNoteBlur"
                  @click="handleNoteClick($event, pageIndex, lineIndex)"
                  @keydown="handleKeyDown($event, pageIndex, lineIndex)"
                >
                  <!-- 音符渲染区域 -->
                  <div class="notes-container" :class="{'notes-justify': alignMode === 'justify'}">
                    <!-- 虚拟光标显示 - 在行首位置 -->
                    <div
                      v-if="cursorPosition.page === pageIndex && cursorPosition.line === lineIndex && cursorPosition.noteIndex === -1 && cursorPosition.visible"
                      class="virtual-cursor"
                    ></div>
  
                    <!-- 音符渲染 -->
                    <template v-for="(note, noteIndex) in line.notes" :key="'note-' + pageIndex + '-' + lineIndex + '-' + noteIndex">
                      <div class="note-wrapper">
                        <span 
                          class="note-span"
                          :class="{ 
                            'selected': isNoteSelected(pageIndex, lineIndex, noteIndex)
                          }"
                          :data-index="noteIndex"
                          :data-id="note.id"
                          :data-page="pageIndex" 
                          :data-line="lineIndex"
                          v-html="note.html"
                        ></span>
                      </div>
                      
                      <!-- 音符后的虚拟光标 -->
                      <div
                        v-if="cursorPosition.page === pageIndex && cursorPosition.line === lineIndex && cursorPosition.noteIndex === noteIndex && cursorPosition.visible"
                        class="virtual-cursor"
                      ></div>
                    </template>
                    
                    <!-- 空白提示 -->
                    <div v-if="line.notes.length === 0" class="empty-placeholder">点击此处添加音符</div>
                  </div>
                  
                  <!-- 歌词显示和编辑区域 -->
                  <div class="lyric-display-container" :class="{'lyric-justify': alignMode === 'justify'}" @click.stop="enterLyricEditMode(pageIndex, lineIndex)">
                    <div class="lyric-display" v-if="!lyricEditing || lyricEditing.page !== pageIndex || lyricEditing.line !== lineIndex">
                      {{ pages[pageIndex].lines[lineIndex].lyrics || '' }}
                    </div>
                    <input
                      v-else
                      class="lyric-input"
                      :class="{'lyric-input-justify': alignMode === 'justify'}"
                      ref="lyricInputRef"
                      v-model="pages[pageIndex].lines[lineIndex].lyrics"
                      @keydown="onLyricInputKeydown($event, pageIndex, lineIndex)"
                      @blur="onLyricInputBlur($event, pageIndex, lineIndex)"
                      placeholder="输入歌词"
                      autocomplete="off"
                    />
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
  
        <!-- 底部状态栏 -->
        <div class="bottom-status-bar">
          <div class="page-info">第 {{ currentLine.page + 1 }} 页 | 行 {{ currentLine.line + 1 }}</div>
        </div>
      </div>
    </div>
  </template>
  
  <script setup lang="ts">
  import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue';
  import type { Ref } from 'vue';
  import MakeScore from './makeScore.vue';
  
  // UUID生成函数
  const generateUUID = (): string => {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
      const r = Math.random() * 16 | 0;
      const v = c === 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
    });
  };
  
  // 缩放百分比
  const zoom = ref(100);
  const scrollContainerRef = ref<HTMLElement | null>(null);
  
  // 歌词输入引用
  const lyricInputRef = ref<HTMLInputElement | null>(null);
  
  // 歌词编辑状态
  const lyricEditing = ref<{ page: number; line: number } | null>(null);
  
  // 音符对齐模式: 'left' 或 'justify'
  const alignMode = ref<'left' | 'justify'>('left');
  
  // 设置对齐模式
  const setAlignMode = (mode: 'left' | 'justify') => {
    alignMode.value = mode;
    saveHistory();
  };
  
  // 计算文本音节数（如果需要）
  const calculateSyllables = (text: string): number => {
    if (!text) return 0;
    
    // 简单实现：每个中文字符算一个音节，英文单词根据元音数量
    
    // 中文字符计数
    const chineseCount = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
    
    // 英文单词处理
    const englishText = text.replace(/[\u4e00-\u9fa5]/g, '');
    const englishWords = englishText.match(/[a-zA-Z]+/g) || [];
    let englishSyllables = 0;
    
    for (const word of englishWords) {
      // 简单计算英文单词音节：元音数量
      const vowelMatches = word.match(/[aeiouy]+/gi);
      englishSyllables += vowelMatches ? vowelMatches.length : 1;
    }
    
    return Math.max(1, chineseCount + englishSyllables);
  };
  
  // 编辑器相关引用
  const pageRefs = ref<HTMLElement[]>([]);
  const currentLine = ref({ page: 0, line: 0 });
  
  // 剪贴板数据
  const clipboardData = ref<MusicNote[]>([]);
  
  // 记录点击的音符区域，确保正确的光标位置
  const activeNoteArea = ref<HTMLElement | null>(null);
  
  // 光标闪烁相关
  const showCursor = ref(true);
  const cursorBlinkInterval = ref<number | null>(null);
  
  // 音符数据模型
  interface MusicNote {
    name: string;    // 音符类型名称
    value: string;   // 音符显示的值
    type?: string;   // 可选的额外类型信息
    html?: string;   // 渲染用HTML内容
    id: string;      // 新增：唯一标识符
    lyricIds: string[];  // 新增：关联的歌词ID数组
  }
  
  // 页面数据模型
  interface LyricItem {
    id: string;
    text: string;
    startNoteId: string;
    endNoteId?: string;
    syllableCount: number;
  }
  
  interface MusicLine {
    notes: MusicNote[];  // 使用数组替代原来的content字符串
    lyrics: LyricItem[]; // 新增：替代原来的单一lyric字段
    lyricEditing?: boolean; // 保留原来的编辑状态字段，过渡期使用
  }
  
  interface Page {
    lines: MusicLine[];
  }
  
  // 页面数据
  const pages = ref<Page[]>([
    {
      lines: [{ 
        notes: [],
        lyrics: [] // 确保包含lyrics字段
      }],
    },
  ]);
  
  // 虚拟光标位置
  const cursorPosition = ref({
    page: 0,
    line: 0,
    noteIndex: -1,  // -1表示在行首，其他值表示在该音符后面
    visible: true
  });
  
  // 选择范围
  const selection = ref({
    active: false,
    startPage: 0,
    startLine: 0,
    startNote: -1,
    endPage: 0,
    endLine: 0,
    endNote: -1
  });
  
  // 响应式数据
  const state = reactive({
    history: [] as string[],
    historyIndex: -1,
  });
  
  // 是否阻止历史记录保存
  const preventHistorySave = ref(false);
  
  // 辅助函数判断音符区域是否激活
  const isNoteAreaActive = (pageIndex: number, lineIndex: number) => {
    return currentLine.value.page === pageIndex && currentLine.value.line === lineIndex;
  };
  
  // 判断音符是否被选中
  const isNoteSelected = (pageIndex: number, lineIndex: number, noteIndex: number) => {
    if (!selection.value.active) return false;
    
    // 获取选择范围的起始和结束位置
    const { startPage, startLine, startNote, endPage, endLine, endNote } = selection.value;
    
    // 检查当前音符是否在选择范围内
    if (pageIndex < startPage || pageIndex > endPage) return false;
    if (pageIndex === startPage && lineIndex < startLine) return false;
    if (pageIndex === endPage && lineIndex > endLine) return false;
    if (pageIndex === startPage && lineIndex === startLine && noteIndex < startNote) return false;
    if (pageIndex === endPage && lineIndex === endLine && noteIndex > endNote) return false;
    
    return true;
  };
  
  // 判断光标是否在音符位置
  const isCursorAtNote = (pageIndex: number, lineIndex: number, noteIndex: number) => {
    return cursorPosition.value.page === pageIndex && 
           cursorPosition.value.line === lineIndex && 
           cursorPosition.value.noteIndex === noteIndex;
  };
  
  // 获取光标样式
  const getCursorStyle = (pageIndex: number, lineIndex: number) => {
    if (cursorPosition.value.page !== pageIndex || cursorPosition.value.line !== lineIndex) {
      return { display: 'none' };
    }
    
    // 根据音符位置计算光标位置
    const noteArea = getNoteAreaElement(pageIndex, lineIndex);
    if (!noteArea) return { display: 'none' };
    
    if (cursorPosition.value.noteIndex === -1) {
      // 在行首
      return {
        left: '0px',
        height: '1.8em',
        top: '5px',
        position: 'absolute',
        width: '2px',
        backgroundColor: '#000',
        animation: 'cursorBlink 1s infinite'
      };
    } else {
      // 找到对应的音符元素
      const noteElements = noteArea.querySelectorAll('.music-symbol');
      if (cursorPosition.value.noteIndex < noteElements.length) {
        const noteElement = noteElements[cursorPosition.value.noteIndex] as HTMLElement;
        if (noteElement) {
          // 计算光标位置在音符后面
          return {
            left: `${noteElement.offsetLeft + noteElement.offsetWidth}px`,
            height: '1.8em',
            top: '5px',
            position: 'absolute',
            width: '2px',
            backgroundColor: '#000',
            animation: 'cursorBlink 1s infinite'
          };
        }
      }
      
      // 如果找不到对应音符，放在最后
      return {
        right: '0px',
        height: '1.8em',
        top: '5px',
        position: 'absolute',
        width: '2px',
        backgroundColor: '#000',
        animation: 'cursorBlink 1s infinite'
      };
    }
  };
  
  // 启动光标闪烁
  const startCursorBlink = () => {
    if (cursorBlinkInterval.value) {
      clearInterval(cursorBlinkInterval.value);
    }
    
    cursorBlinkInterval.value = window.setInterval(() => {
      showCursor.value = !showCursor.value;
    }, 500);
  };
  
  // 重置光标闪烁
  const resetCursorBlink = () => {
    showCursor.value = true;
    startCursorBlink();
  };
  
  // 将HTML内容转换为音符数组
  const htmlToNotes = (htmlContent: string): MusicNote[] => {
    const notes: MusicNote[] = [];
    
    // 创建一个临时div来解析HTML
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = htmlContent;
    
    // 查找所有音符元素
    const symbols = tempDiv.querySelectorAll('.music-symbol');
    symbols.forEach(symbol => {
      const name = symbol.getAttribute('data-note-type') || '';
      const value = symbol.textContent || '';
      
      notes.push({
        name,
        value,
        type: symbol.getAttribute('data-note-type') || undefined,
        html: symbol.outerHTML, // 添加HTML内容
        id: symbol.getAttribute('data-note-id') || generateUUID(),
        lyricIds: symbol.getAttribute('data-lyric-ids') ? symbol.getAttribute('data-lyric-ids')!.split(',') : []
      });
    });
    
    return notes;
  };
  
  // 将当前数据模型转换为新格式
  const convertDataModel = () => {
    // 创建新的数据结构
    const newPages: Page[] = [];
    
    // 转换每一页
    pages.value.forEach((page: any) => {
      const newPage: Page = {
        lines: []
      };
      
      // 转换每一行
      page.lines.forEach((line: any) => {
        // 使用类型断言访问旧的content属性
        const oldContent = (line as any).content || '';
        
        const newLine: MusicLine = {
          notes: oldContent ? htmlToNotes(oldContent) : [],
          lyrics: Array.isArray(line.lyrics) ? line.lyrics : []  // 使用现有的lyrics或创建空数组
        };
        
        newPage.lines.push(newLine);
      });
      
      newPages.push(newPage);
    });
    
    // 更新数据模型
    pages.value = newPages;
  };
  
  // 修复alignLyricWithNotes中的空指针问题
  const alignLyricWithNotes = (pageIndex: number, lineIndex: number) => {
    const line = pages.value[pageIndex]?.lines[lineIndex];
    if (!line || line.lyrics.length === 0) return;
    
    const notesCount = line.notes.length;
    const lyricContainer = document.querySelector(
      `.note-area[data-page="${pageIndex}"][data-line="${lineIndex}"] .lyric-display`
    );
    
    if (!lyricContainer) return;
    
    // 清除旧的样式
    if (alignMode.value === 'justify' && notesCount > 0) {
      // 在两端对齐模式下，给歌词容器添加必要的样式
      if (notesCount > (lyricContainer.textContent || '').length) {
        (lyricContainer as HTMLElement).style.justifyContent = 'space-between';
      } else {
        (lyricContainer as HTMLElement).style.justifyContent = 'space-around';
      }
    } else {
      // 左对齐模式下的处理
      (lyricContainer as HTMLElement).style.justifyContent = 'flex-start';
    }
  };
  
  // 监听页面变化，确保DOM更新后有效的光标
  watch(
    pages,
    () => {
      nextTick(() => {
        console.log('pages-先执行了这个吗', pages.value);
        // 确保当前行有效
        const { page, line } = currentLine.value;
        if (pages.value[page] && pages.value[page].lines[line]) {
          const noteArea = getNoteAreaElement(page, line);
          if (noteArea) {
            activeNoteArea.value = noteArea;
            noteArea.focus();
          }
        } else if (pages.value.length > 0) {
          // 如果当前行无效，设置为第一行
          const lastPage = pages.value.length - 1;
          const lastLine = pages.value[lastPage].lines.length - 1;
          currentLine.value = {
            page: lastPage >= 0 ? lastPage : 0,
            line: lastLine >= 0 ? lastLine : 0,
          };
  
          nextTick(() => {
            const noteArea = getNoteAreaElement(currentLine.value.page, currentLine.value.line);
            if (noteArea) {
              activeNoteArea.value = noteArea;
              noteArea.focus();
              // 将光标移到末尾
              cursorPosition.value = {
                page: currentLine.value.page,
                line: currentLine.value.line,
                noteIndex: pages.value[currentLine.value.page].lines[currentLine.value.line].notes.length - 1,
                visible: true
              };
            }
          });
        }
      });
    },
    { deep: true }
  );
  
  // 检查当前页面是否为空
  const isCurrentPageEmpty = (): boolean => {
    const { page } = cursorPosition.value;
    
    // 检查页面是否存在
    if (page < 0 || page >= pages.value.length) return false;
    
    // 检查页面是否只有一行，且该行为空
    return pages.value[page].lines.length === 1 && 
           pages.value[page].lines[0].notes.length === 0;
  };
  
  // 获取特定行的音符区域元素
  const getNoteAreaElement = (pageIndex: number, lineIndex: number): HTMLElement | null => {
    const selector = `.note-area[data-page="${pageIndex}"][data-line="${lineIndex}"]`;
    return document.querySelector(selector) as HTMLElement | null;
  };
  
  // 确保指定的页面和行存在
  const ensurePageAndLineExist = (pageIndex: number, lineIndex: number) => {
    // 确保页面存在
    while (pages.value.length <= pageIndex) {
      pages.value.push({ lines: [] });
    }
  
    // 确保行存在
    while (pages.value[pageIndex].lines.length <= lineIndex) {
      pages.value[pageIndex].lines.push({ 
        notes: [],
        lyrics: [] // 确保包含lyrics字段
      });
    }
  };
  
  // 处理滚轮缩放
  const handleWheel = (e: WheelEvent) => {
    // 如果按住Ctrl键，则缩放而不是滚动
    if (e.ctrlKey || e.metaKey) {
      e.preventDefault();
      
      // 缩放步长
      const delta = e.deltaY > 0 ? -5 : 5;
      
      // 限制缩放范围
      zoom.value = Math.max(50, Math.min(150, zoom.value + delta));
    }
  };
  
  // 添加新页面
  const addNewPage = () => {
    // 添加新页
    pages.value.push({
      lines: [{ 
        notes: [],
        lyrics: []
      }]
    });
  
    // 保存历史记录
    saveHistory();
  };
  
  // 删除当前页面（如果为空）
  const removeCurrentPageIfEmpty = () => {
    const { page } = currentLine.value;
  
    // 不能删除第一页
    if (page === 0) return;
  
    // 检查页面是否为空
    if (isCurrentPageEmpty()) {
      // 删除当前页
      pages.value.splice(page, 1);
  
      // 移动到前一页
      currentLine.value = {
        page: page - 1,
        line: pages.value[page - 1].lines.length - 1
      };
      
      // 保存历史记录
      saveHistory();
    }
  };
  
  // 添加歌词行
  const addLyricLine = () => {
    const { page, line } = currentLine.value;
    
    // 确保当前行存在
    ensurePageAndLineExist(page, line);
    
    // 切换歌词显示状态（如果已有歌词则显示编辑界面，如果没有则创建）
    if (pages.value[page].lines[line].lyrics !== undefined) {
      // 已有歌词，切换到编辑模式
      pages.value[page].lines[line].lyricEditing = !pages.value[page].lines[line].lyricEditing;
    } else {
      // 添加歌词字段
      pages.value[page].lines[line].lyrics = [];
      // 进入编辑模式
      pages.value[page].lines[line].lyricEditing = true;
    }
    
    // 保存历史记录
    saveHistory();
    
    // 在下一个渲染周期聚焦到歌词输入框
    nextTick(() => {
      if (pages.value[page].lines[line].lyricEditing) {
        const lyricInput = getLyricInputElement(page, line);
        if (lyricInput) {
          lyricInput.focus();
        }
      }
    });
  };
  
  // 获取歌词输入框元素
  const getLyricInputElement = (pageIndex: number, lineIndex: number): HTMLElement | null => {
    const selector = `.lyric-input[data-page="${pageIndex}"][data-line="${lineIndex}"]`;
    return document.querySelector(selector) as HTMLElement | null;
  };
  
  // 处理歌词输入完成
  const onLyricInputBlur = (event: FocusEvent, pageIndex: number, lineIndex: number) => {
    // 获取输入内容
    const lyricText = (event.target as HTMLInputElement).value;
    
    // 更新歌词内容，确保每个字符之间有适当间距
    pages.value[pageIndex].lines[lineIndex].lyrics = lyricText.split(' ').map(word => ({
      id: generateUUID(),
      text: word,
      startNoteId: '',
      endNoteId: '',
      syllableCount: word.length,
      color: '#000'
    }));
    
    // 退出编辑模式
    pages.value[pageIndex].lines[lineIndex].lyricEditing = false;
    
    // 保存历史记录
    saveHistory();
    
    // 更新歌词字符与音符的对应关系
    nextTick(() => {
      alignLyricWithNotes(pageIndex, lineIndex);
    });
  };
  
  // 处理歌词输入回车事件
  const onLyricInputKeydown = (event: KeyboardEvent, pageIndex: number, lineIndex: number) => {
    // 阻止事件冒泡，防止触发音符区域的键盘事件
    event.stopPropagation();
    
    // 按下回车键时，保存歌词内容
    if (event.key === 'Enter') {
      // 阻止默认行为
      event.preventDefault();
      
      // 获取输入内容
      const lyricText = (event.target as HTMLInputElement).value;
      
      // 更新歌词内容
      pages.value[pageIndex].lines[lineIndex].lyrics = lyricText.split(' ').map(word => ({
        id: generateUUID(),
        text: word,
        startNoteId: '',
        endNoteId: '',
        syllableCount: word.length,
        color: '#000'
      }));
      
      // 退出编辑模式
      pages.value[pageIndex].lines[lineIndex].lyricEditing = false;
      
      // 保存历史记录
      saveHistory();
      
      // 聚焦回音符区域
      const noteArea = getNoteAreaElement(pageIndex, lineIndex);
      if (noteArea) {
        nextTick(() => {
          noteArea.focus();
          activeNoteArea.value = noteArea;
          
          // 恢复光标可见性
          cursorPosition.value.visible = true;
        });
      }
    }
    // 处理Escape键，取消编辑
    else if (event.key === 'Escape') {
      // 阻止默认行为
      event.preventDefault();
      
      // 退出编辑模式，不保存更改
      pages.value[pageIndex].lines[lineIndex].lyricEditing = false;
      
      // 聚焦回音符区域
      const noteArea = getNoteAreaElement(pageIndex, lineIndex);
      if (noteArea) {
        nextTick(() => {
          noteArea.focus();
          activeNoteArea.value = noteArea;
          
          // 恢复光标可见性
          cursorPosition.value.visible = true;
        });
      }
    }
    // 处理删除键，如果输入框为空，则删除整个歌词行
    else if ((event.key === 'Backspace' || event.key === 'Delete') && 
             (event.target as HTMLInputElement).value === '') {
      // 阻止默认行为
      event.preventDefault();
      
      // 删除歌词行
      removeLyric(pageIndex, lineIndex);
      
      // 聚焦回音符区域
      const noteArea = getNoteAreaElement(pageIndex, lineIndex);
      if (noteArea) {
        nextTick(() => {
          noteArea.focus();
          activeNoteArea.value = noteArea;
          
          // 恢复光标可见性
          cursorPosition.value.visible = true;
        });
      }
    }
  };
  
  // 删除歌词行
  const removeLyric = (pageIndex: number, lineIndex: number, event?: MouseEvent) => {
    console.log('删除歌词行:', pageIndex, lineIndex);
    
    // 阻止事件冒泡，防止触发音符区域的点击事件
    if (event) {
      event.stopPropagation();
      event.preventDefault();
    }
    
    // 确保页面和行存在
    if (pageIndex < 0 || pageIndex >= pages.value.length ||
        lineIndex < 0 || lineIndex >= pages.value[pageIndex].lines.length) {
      console.warn('无效的页面或行索引');
      return;
    }
    
    // 清空歌词数组而不是删除属性
    pages.value[pageIndex].lines[lineIndex].lyrics = [];
    // 退出编辑模式
    pages.value[pageIndex].lines[lineIndex].lyricEditing = false;
    
    // 保存历史记录
    saveHistory();
    
    console.log('歌词行已删除');
  };
  
  // 历史记录管理
  const saveHistory = () => {
    // 如果禁止保存，则直接返回
    if (preventHistorySave.value) return;
    
    // 序列化整个编辑器状态
    const editorState = JSON.stringify(pages.value);
  
    // 避免重复保存相同状态
    if (state.history.length > 0 && 
        state.historyIndex >= 0 && 
        state.history[state.historyIndex] === editorState) {
      console.log('状态未变，不保存历史');
      return;
    }
  
    state.history = state.history.slice(0, state.historyIndex + 1);
    state.history.push(editorState);
    state.historyIndex = state.history.length - 1;
    
    console.log('保存历史记录 #', state.historyIndex);
  };
  
  // 处理复制操作
  const handleCopy = () => {
    console.log('开始复制操作, 选择状态:', selection.value.active);
    
    // 如果没有选中内容，不进行任何操作
    if (!selection.value.active) {
      console.log('没有选中内容，无法复制');
      return;
    }
    
    const { startPage, startLine, startNote, endPage, endLine, endNote } = selection.value;
    console.log('复制范围:', startPage, startLine, startNote, '到', endPage, endLine, endNote);
    
    // 收集选中的音符
    const copiedNotes = [];
    
    try {
      // 如果选择范围在同一行
      if (startPage === endPage && startLine === endLine) {
        // 将该行中的选中音符添加到复制列表
        for (let i = startNote; i <= endNote; i++) {
          if (i < pages.value[startPage].lines[startLine].notes.length) {
            copiedNotes.push(JSON.parse(JSON.stringify(pages.value[startPage].lines[startLine].notes[i])));
          }
        }
      } else {
        // 处理跨行或跨页的选择
        
        // 第一行: 添加开始位置之后的所有音符
        const firstLineNotes = pages.value[startPage].lines[startLine].notes;
        for (let i = startNote; i < firstLineNotes.length; i++) {
          copiedNotes.push(JSON.parse(JSON.stringify(firstLineNotes[i])));
        }
        
        // 中间所有行: 添加全部音符
        // 同一页内的中间行
        if (startPage === endPage) {
          for (let i = startLine + 1; i < endLine; i++) {
            const lineNotes = pages.value[startPage].lines[i].notes;
            for (let j = 0; j < lineNotes.length; j++) {
              copiedNotes.push(JSON.parse(JSON.stringify(lineNotes[j])));
            }
          }
        } else {
          // 跨页的中间行
          
          // 起始页中间行
          for (let i = startLine + 1; i < pages.value[startPage].lines.length; i++) {
            const lineNotes = pages.value[startPage].lines[i].notes;
            for (let j = 0; j < lineNotes.length; j++) {
              copiedNotes.push(JSON.parse(JSON.stringify(lineNotes[j])));
            }
          }
          
          // 中间页的所有行
          for (let p = startPage + 1; p < endPage; p++) {
            for (let i = 0; i < pages.value[p].lines.length; i++) {
              const lineNotes = pages.value[p].lines[i].notes;
              for (let j = 0; j < lineNotes.length; j++) {
                copiedNotes.push(JSON.parse(JSON.stringify(lineNotes[j])));
              }
            }
          }
          
          // 结束页前面的行
          for (let i = 0; i < endLine; i++) {
            const lineNotes = pages.value[endPage].lines[i].notes;
            for (let j = 0; j < lineNotes.length; j++) {
              copiedNotes.push(JSON.parse(JSON.stringify(lineNotes[j])));
            }
          }
        }
        
        // 最后一行: 添加结束位置之前的所有音符
        if (endPage < pages.value.length && endLine < pages.value[endPage].lines.length) {
          const lastLineNotes = pages.value[endPage].lines[endLine].notes;
          for (let i = 0; i <= endNote && i < lastLineNotes.length; i++) {
            copiedNotes.push(JSON.parse(JSON.stringify(lastLineNotes[i])));
          }
        }
      }
      
      console.log('已收集到的音符数量:', copiedNotes.length);
      
      // 存储到本地剪贴板变量中
      clipboardData.value = copiedNotes;
      
      // 创建一个特殊标记，表明这是音符数据
      const musicNoteData = {
        type: "XMusicScore-notes",
        version: "1.0",
        data: copiedNotes
      };
      
      // 尝试存储到系统剪贴板
      try {
        // 将音符转换为可保存的格式
        const clipboardText = JSON.stringify(musicNoteData);
        console.log('准备复制到系统剪贴板，数据长度:', clipboardText.length);
        
        // 保存到剪贴板
        if (navigator.clipboard && navigator.clipboard.writeText) {
          navigator.clipboard.writeText(clipboardText).then(() => {
            console.log('已复制音符到系统剪贴板');
          }).catch((error: any) => {
            console.error('无法复制到系统剪贴板, 但已保存在内部剪贴板中:', error.message);
          });
        } else {
          // 创建临时文本区域
          const textArea = document.createElement('textarea');
          textArea.value = clipboardText;
          document.body.appendChild(textArea);
          textArea.select();
          
          // 尝试使用document.execCommand复制
          const successful = document.execCommand('copy');
          if (successful) {
            console.log('使用传统方法成功复制到剪贴板');
          } else {
            console.warn('传统方法复制失败，但已保存到内部剪贴板');
          }
          
          // 移除临时元素
          document.body.removeChild(textArea);
        }
      } catch (error: any) {
        console.error('复制到系统剪贴板失败, 但已保存在内部剪贴板中:', error.message);
      }
    } catch (error: any) {
      console.error('复制操作出错:', error.message);
    }
  };
  
  // 处理粘贴操作
  const handlePaste = async () => {
    console.log('开始粘贴操作');
    
    try {
      let notesToPaste = [];
      let pasteSuccess = false;
      
      // 首先尝试从系统剪贴板获取数据
      try {
        if (navigator.clipboard && navigator.clipboard.readText) {
          const clipboardText = await navigator.clipboard.readText();
          console.log('从系统剪贴板读取的文本长度:', clipboardText ? clipboardText.length : 0);
          
          // 尝试解析剪贴板数据
          if (clipboardText && clipboardText.trim()) {
            try {
              const parsedData = JSON.parse(clipboardText);
              console.log('解析的数据类型:', parsedData ? typeof parsedData : 'null');
              
              // 首先检查是否是我们的特殊格式
              if (parsedData && parsedData.type === "XMusicScore-notes" && Array.isArray(parsedData.data)) {
                notesToPaste = parsedData.data;
                pasteSuccess = true;
                console.log('从特殊格式中获取音符数量:', notesToPaste.length);
              }
              // 验证解析出的数据是否为音符数组
              else if (Array.isArray(parsedData) && parsedData.length > 0 && 
                  parsedData.every(note => note && typeof note === 'object' && 'value' in note)) {
                notesToPaste = parsedData;
                pasteSuccess = true;
                console.log('从系统剪贴板获取到的音符数量:', notesToPaste.length);
              } else {
                console.warn('系统剪贴板中的数据不是有效的音符格式:', typeof parsedData);
              }
            } catch (error: any) {
              console.warn('解析系统剪贴板数据失败，不是有效的JSON:', error.message);
              // 剪贴板内容不是JSON，可能是普通文本
              // 这里我们可以选择不处理或者创建简单的音符
            }
          } else {
            console.warn('系统剪贴板为空');
          }
        } else {
          console.warn('浏览器不支持Clipboard API');
        }
      } catch (error: any) {
        console.warn('读取系统剪贴板失败:', error.message);
      }
      
      // 如果系统剪贴板粘贴失败，则使用内部剪贴板
      if (!pasteSuccess && clipboardData.value && clipboardData.value.length > 0) {
        notesToPaste = JSON.parse(JSON.stringify(clipboardData.value));
        pasteSuccess = true;
        console.log('使用内部剪贴板中的音符数量:', notesToPaste.length);
      }
      
      // 如果没有可粘贴的内容，直接返回
      if (!pasteSuccess || notesToPaste.length === 0) {
        console.warn('没有可粘贴的内容');
        return;
      }
      
      // 如果有选中内容，先删除选中内容
      if (selection.value.active) {
        deleteSelectedNotes();
      }
      
      // 获取当前光标位置
      const { page, line, noteIndex } = cursorPosition.value;
      
      // 确保页面和行存在
      ensurePageAndLineExist(page, line);
      
      const currentLineNotes = pages.value[page].lines[line].notes;
      
      // 确定插入位置
      let insertIndex = noteIndex + 1;
      if (noteIndex === -1) {
        insertIndex = 0;
      }
      
      console.log('准备插入音符, 位置:', page, line, insertIndex);
      
      // 插入音符
      for (let i = 0; i < notesToPaste.length; i++) {
        const noteToInsert = JSON.parse(JSON.stringify(notesToPaste[i]));
        // 确保音符有必要的字段
        if (!noteToInsert.html && noteToInsert.value) {
          noteToInsert.html = `<span class="music-symbol" data-note-type="${noteToInsert.name || ''}">${noteToInsert.value}</span>`;
        }
        currentLineNotes.splice(insertIndex + i, 0, noteToInsert);
      }
      
      // 更新光标位置到粘贴内容的末尾
      cursorPosition.value = {
        page,
        line,
        noteIndex: insertIndex + notesToPaste.length - 1,
        visible: true
      };
      
      // 清除选择状态
      selection.value.active = false;
      
      // 重置光标闪烁
      resetCursorBlink();
      
      // 保存历史记录
      saveHistory();
      
      console.log('粘贴完成，共插入音符:', notesToPaste.length);
    } catch (error: any) {
      console.error('粘贴操作发生错误:', error);
    }
  };
  
  // 删除选中的音符
  const deleteSelectedNotes = () => {
    console.log('开始删除选中音符');
    
    if (!selection.value.active) {
      console.log('没有选中内容，无法删除');
      return;
    }
    
    const { startPage, startLine, startNote, endPage, endLine, endNote } = selection.value;
    console.log('删除范围:', startPage, startLine, startNote, '到', endPage, endLine, endNote);
    
    // 如果选择范围在同一行
    if (startPage === endPage && startLine === endLine) {
      // 检查起始和结束索引是否有效
      if (startNote <= endNote && 
          startNote >= 0 && 
          endNote < pages.value[startPage].lines[startLine].notes.length) {
        
        // 删除该行中的选中音符
        const notesToDelete = endNote - startNote + 1;
        console.log('在同一行中删除音符数量:', notesToDelete);
        pages.value[startPage].lines[startLine].notes.splice(startNote, notesToDelete);
        
        // 更新光标位置
        cursorPosition.value = {
          page: startPage,
          line: startLine,
          noteIndex: startNote - 1 >= -1 ? startNote - 1 : -1,
          visible: true
        };
      } else {
        console.warn('选择范围无效');
      }
    } else {
      // 处理跨行或跨页的选择 - 这需要更复杂的逻辑
      
      // 第一行: 保留开始位置之前的所有音符
      const firstLineNotes = pages.value[startPage].lines[startLine].notes.slice(0, startNote);
      
      // 最后一行: 保留结束位置之后的所有音符
      const lastLineNotes = pages.value[endPage].lines[endLine].notes.slice(endNote + 1);
      
      // 合并第一行与最后一行
      const mergedNotes = [...firstLineNotes, ...lastLineNotes];
      console.log('合并后的音符数量:', mergedNotes.length);
      
      // 更新第一行的音符
      pages.value[startPage].lines[startLine].notes = mergedNotes;
      
      // 如果是在同一页内
      if (startPage === endPage) {
        // 删除中间的所有行
        console.log('删除同一页内的行数:', endLine - startLine);
        pages.value[startPage].lines.splice(startLine + 1, endLine - startLine);
      } else {
        // 跨页删除处理
        
        // 删除第一页中startLine之后的所有行
        pages.value[startPage].lines.splice(startLine + 1);
        
        // 删除中间所有页
        if (endPage - startPage > 1) {
          pages.value.splice(startPage + 1, endPage - startPage - 1);
        }
        
        // 删除最后一页中endLine之前的所有行
        const adjustedEndPage = startPage + 1; // 因为中间页已被删除
        if (adjustedEndPage < pages.value.length && endLine < pages.value[adjustedEndPage].lines.length) {
          pages.value[adjustedEndPage].lines.splice(0, endLine);
          
          // 如果最后一页没有行了，删除该页
          if (pages.value[adjustedEndPage].lines.length === 0) {
            pages.value.splice(adjustedEndPage, 1);
          }
        }
      }
      
      // 更新光标位置到合并后的位置
      cursorPosition.value = {
        page: startPage,
        line: startLine,
        noteIndex: firstLineNotes.length - 1 >= -1 ? firstLineNotes.length - 1 : -1,
        visible: true
      };
    }
    
    // 重置选择状态
    selection.value.active = false;
    
    // 聚焦到音符区域
    const noteArea = getNoteAreaElement(cursorPosition.value.page, cursorPosition.value.line);
    if (noteArea) {
      noteArea.focus();
      activeNoteArea.value = noteArea;
    }
    
    // 保存历史记录
    saveHistory();
    
    console.log('删除选中音符完成');
  };
  
  // 组件初始化
  onMounted(() => {
    // 转换现有数据模型
    convertDataModel();
    
    // 初始化
    saveHistory();
    
    // 启动光标闪烁
    startCursorBlink();
  
    // 确保默认页面有焦点
    nextTick(() => {
      const firstNoteArea = getNoteAreaElement(0, 0);
      if (firstNoteArea) {
        firstNoteArea.focus();
        activeNoteArea.value = firstNoteArea;
        
        // 设置初始光标位置
        cursorPosition.value = {
          page: 0,
          line: 0,
          noteIndex: -1,
          visible: true
        };
      }
    });
  });
  
  // 处理音符区域获得焦点
  const handleNoteFocus = (event: FocusEvent, pageIndex: number, lineIndex: number) => {
    // 更新当前行
    currentLine.value = { page: pageIndex, line: lineIndex };
    
    // 记录激活的音符区域
    activeNoteArea.value = event.target as HTMLElement;
    
    // 重置光标闪烁
    resetCursorBlink();
    
    console.log('音符区域获得焦点:', pageIndex, lineIndex);
  };
  
  // 处理音符区域失去焦点
  const handleNoteBlur = () => {
    // 可能需要处理失去焦点的逻辑，如保存状态等
    console.log('音符区域失去焦点');
  };
  
  // 处理音符区域点击
  const handleNoteClick = (event: MouseEvent, pageIndex: number, lineIndex: number) => {
    // 阻止可能的默认行为
    event.preventDefault();
    
    // 记录当前行
    currentLine.value = { page: pageIndex, line: lineIndex };
    
    // 获取点击的位置
    const clickX = event.clientX;
    
    // 获取音符区域
    const noteArea = event.currentTarget as HTMLElement;
    activeNoteArea.value = noteArea;
    
    // 计算点击位置在哪个音符附近
    const noteElements = noteArea.querySelectorAll('.note-span');
    let closestNoteIndex = -1;
    let minDistance = Infinity;
    
    noteElements.forEach((noteElement, index) => {
      const rect = (noteElement as HTMLElement).getBoundingClientRect();
      const noteCenter = rect.left + rect.width / 2;
      const distance = Math.abs(clickX - noteCenter);
      
      // 如果是最近的音符，记录索引
      if (distance < minDistance) {
        minDistance = distance;
        closestNoteIndex = index;
      }
    });
    
    // 更新光标位置
    cursorPosition.value = {
      page: pageIndex,
      line: lineIndex,
      noteIndex: closestNoteIndex,
      visible: true
    };
    
    // 如果是双击，可以选择整个音符
    if (event.detail === 2 && closestNoteIndex !== -1) {
      // 设置选择范围为当前音符
      selection.value = {
        active: true,
        startPage: pageIndex,
        startLine: lineIndex,
        startNote: closestNoteIndex,
        endPage: pageIndex,
        endLine: lineIndex,
        endNote: closestNoteIndex
      };
    } else {
      // 单击，清除选择
      selection.value.active = false;
    }
    
    // 重置光标闪烁
    resetCursorBlink();
    
    console.log('点击音符区域:', pageIndex, lineIndex, '最近的音符索引:', closestNoteIndex);
  };
  
  // 处理键盘事件
  const handleKeyDown = (event: KeyboardEvent, pageIndex: number, lineIndex: number) => {
    // 阻止可能的默认行为
    // event.preventDefault();
    
    // 获取当前光标位置
    const { noteIndex } = cursorPosition.value;
    const currentNotes = pages.value[pageIndex].lines[lineIndex].notes;
    
    console.log('键盘事件:', event.key, '当前页面:', pageIndex, '当前行:', lineIndex, '当前音符索引:', noteIndex);
    
    // 处理不同的键盘事件
    switch (event.key) {
      case 'ArrowLeft':
        // 向左移动光标
        event.preventDefault();
        if (noteIndex > -1) {
          // 当前在音符中间，向左移动一个
          cursorPosition.value.noteIndex = noteIndex - 1;
        } else if (noteIndex === -1) {
          // 当前在行首，需要移动到上一行末尾
          if (lineIndex > 0) {
            // 同一页上一行
            const prevLineIndex = lineIndex - 1;
            const prevLineNotes = pages.value[pageIndex].lines[prevLineIndex].notes;
            
            cursorPosition.value = {
              page: pageIndex,
              line: prevLineIndex,
              noteIndex: prevLineNotes.length - 1,
              visible: true
            };
            
            // 更新当前行
            currentLine.value = { page: pageIndex, line: prevLineIndex };
            
            // 聚焦到上一行
            const noteArea = getNoteAreaElement(pageIndex, prevLineIndex);
            if (noteArea) {
              noteArea.focus();
              activeNoteArea.value = noteArea;
            }
          } else if (pageIndex > 0) {
            // 需要移动到上一页的最后一行
            const prevPageIndex = pageIndex - 1;
            const prevPage = pages.value[prevPageIndex];
            const prevLineIndex = prevPage.lines.length - 1;
            const prevLineNotes = prevPage.lines[prevLineIndex].notes;
            
            cursorPosition.value = {
              page: prevPageIndex,
              line: prevLineIndex,
              noteIndex: prevLineNotes.length - 1,
              visible: true
            };
            
            // 更新当前行
            currentLine.value = { page: prevPageIndex, line: prevLineIndex };
            
            // 聚焦到上一页的最后一行
            const noteArea = getNoteAreaElement(prevPageIndex, prevLineIndex);
            if (noteArea) {
              noteArea.focus();
              activeNoteArea.value = noteArea;
            }
          }
        }
        break;
        
      case 'ArrowRight':
        // 向右移动光标
        event.preventDefault();
        if (noteIndex < currentNotes.length - 1) {
          // 当前不在行尾，向右移动一个
          cursorPosition.value.noteIndex = noteIndex + 1;
        } else {
          // 当前在行尾，需要移动到下一行开始
          if (lineIndex < pages.value[pageIndex].lines.length - 1) {
            // 同一页下一行
            const nextLineIndex = lineIndex + 1;
            
            cursorPosition.value = {
              page: pageIndex,
              line: nextLineIndex,
              noteIndex: -1,
              visible: true
            };
            
            // 更新当前行
            currentLine.value = { page: pageIndex, line: nextLineIndex };
            
            // 聚焦到下一行
            const noteArea = getNoteAreaElement(pageIndex, nextLineIndex);
            if (noteArea) {
              noteArea.focus();
              activeNoteArea.value = noteArea;
            }
          } else if (pageIndex < pages.value.length - 1) {
            // 需要移动到下一页的第一行
            const nextPageIndex = pageIndex + 1;
            
            cursorPosition.value = {
              page: nextPageIndex,
              line: 0,
              noteIndex: -1,
              visible: true
            };
            
            // 更新当前行
            currentLine.value = { page: nextPageIndex, line: 0 };
            
            // 聚焦到下一页的第一行
            const noteArea = getNoteAreaElement(nextPageIndex, 0);
            if (noteArea) {
              noteArea.focus();
              activeNoteArea.value = noteArea;
            }
          }
        }
        break;
        
      case 'ArrowUp':
        // 向上移动光标到上一行
        event.preventDefault();
        if (lineIndex > 0) {
          // 同一页上一行
          const prevLineIndex = lineIndex - 1;
          const prevLineNotes = pages.value[pageIndex].lines[prevLineIndex].notes;
          
          // 保持水平相对位置
          let targetNoteIndex = Math.min(noteIndex, prevLineNotes.length - 1);
          
          cursorPosition.value = {
            page: pageIndex,
            line: prevLineIndex,
            noteIndex: targetNoteIndex,
            visible: true
          };
          
          // 更新当前行
          currentLine.value = { page: pageIndex, line: prevLineIndex };
          
          // 聚焦到上一行
          const noteArea = getNoteAreaElement(pageIndex, prevLineIndex);
          if (noteArea) {
            noteArea.focus();
            activeNoteArea.value = noteArea;
          }
        } else if (pageIndex > 0) {
          // 需要移动到上一页的最后一行
          const prevPageIndex = pageIndex - 1;
          const prevPage = pages.value[prevPageIndex];
          const prevLineIndex = prevPage.lines.length - 1;
          const prevLineNotes = prevPage.lines[prevLineIndex].notes;
          
          // 保持水平相对位置
          let targetNoteIndex = Math.min(noteIndex, prevLineNotes.length - 1);
          
          cursorPosition.value = {
            page: prevPageIndex,
            line: prevLineIndex,
            noteIndex: targetNoteIndex,
            visible: true
          };
          
          // 更新当前行
          currentLine.value = { page: prevPageIndex, line: prevLineIndex };
          
          // 聚焦到上一页的最后一行
          const noteArea = getNoteAreaElement(prevPageIndex, prevLineIndex);
          if (noteArea) {
            noteArea.focus();
            activeNoteArea.value = noteArea;
          }
        }
        break;
        
      case 'ArrowDown':
        // 向下移动光标到下一行
        event.preventDefault();
        if (lineIndex < pages.value[pageIndex].lines.length - 1) {
          // 同一页下一行
          const nextLineIndex = lineIndex + 1;
          const nextLineNotes = pages.value[pageIndex].lines[nextLineIndex].notes;
          
          // 保持水平相对位置
          let targetNoteIndex = Math.min(noteIndex, nextLineNotes.length - 1);
          
          cursorPosition.value = {
            page: pageIndex,
            line: nextLineIndex,
            noteIndex: targetNoteIndex,
            visible: true
          };
          
          // 更新当前行
          currentLine.value = { page: pageIndex, line: nextLineIndex };
          
          // 聚焦到下一行
          const noteArea = getNoteAreaElement(pageIndex, nextLineIndex);
          if (noteArea) {
            noteArea.focus();
            activeNoteArea.value = noteArea;
          }
        } else if (pageIndex < pages.value.length - 1) {
          // 需要移动到下一页的第一行
          const nextPageIndex = pageIndex + 1;
          const nextLineNotes = pages.value[nextPageIndex].lines[0].notes;
          
          // 保持水平相对位置
          let targetNoteIndex = Math.min(noteIndex, nextLineNotes.length - 1);
          
          cursorPosition.value = {
            page: nextPageIndex,
            line: 0,
            noteIndex: targetNoteIndex,
            visible: true
          };
          
          // 更新当前行
          currentLine.value = { page: nextPageIndex, line: 0 };
          
          // 聚焦到下一页的第一行
          const noteArea = getNoteAreaElement(nextPageIndex, 0);
          if (noteArea) {
            noteArea.focus();
            activeNoteArea.value = noteArea;
          }
        }
        break;
        
      case 'Delete':
      case 'Backspace':
        // 删除音符
        event.preventDefault();
        
        // 如果有选中内容，删除选中内容
        if (selection.value.active) {
          deleteSelectedNotes();
          return;
        }
        
        // 否则，删除当前光标前/后的音符
        if (event.key === 'Backspace') {
          // 删除光标前的音符
          if (noteIndex > -1) {
            // 删除指定位置的音符
            pages.value[pageIndex].lines[lineIndex].notes.splice(noteIndex, 1);
            
            // 更新光标位置
            cursorPosition.value.noteIndex = noteIndex - 1;
            
            // 保存历史记录
            saveHistory();
          } else if (noteIndex === -1 && (lineIndex > 0 || pageIndex > 0)) {
            // 当前在行首，需要合并到上一行
            if (lineIndex > 0) {
              // 同一页中的上一行
              const prevLineIndex = lineIndex - 1;
              const prevLineNotes = pages.value[pageIndex].lines[prevLineIndex].notes;
              const currentLineNotes = pages.value[pageIndex].lines[lineIndex].notes;
              
              // 记录上一行末尾的索引
              const prevLineEndIndex = prevLineNotes.length - 1;
              
              // 合并当前行到上一行
              pages.value[pageIndex].lines[prevLineIndex].notes = [
                ...prevLineNotes,
                ...currentLineNotes
              ];
              
              // 删除当前行
              pages.value[pageIndex].lines.splice(lineIndex, 1);
              
              // 更新当前行和光标位置
              currentLine.value = { page: pageIndex, line: prevLineIndex };
              cursorPosition.value = {
                page: pageIndex,
                line: prevLineIndex,
                noteIndex: prevLineEndIndex,
                visible: true
              };
              
              // 聚焦到上一行
              const noteArea = getNoteAreaElement(pageIndex, prevLineIndex);
              if (noteArea) {
                noteArea.focus();
                activeNoteArea.value = noteArea;
              }
              
              // 保存历史记录
              saveHistory();
            } else if (pageIndex > 0) {
              // 需要合并到上一页的最后一行
              const prevPageIndex = pageIndex - 1;
              const prevPage = pages.value[prevPageIndex];
              const prevLineIndex = prevPage.lines.length - 1;
              const prevLineNotes = prevPage.lines[prevLineIndex].notes;
              const currentLineNotes = pages.value[pageIndex].lines[0].notes;
              
              // 记录上一行末尾的索引
              const prevLineEndIndex = prevLineNotes.length - 1;
              
              // 合并当前行到上一页的最后一行
              pages.value[prevPageIndex].lines[prevLineIndex].notes = [
                ...prevLineNotes,
                ...currentLineNotes
              ];
              
              // 如果当前页只有这一行，删除整个页面，否则只删除第一行
              if (pages.value[pageIndex].lines.length === 1) {
                pages.value.splice(pageIndex, 1);
              } else {
                pages.value[pageIndex].lines.splice(0, 1);
              }
              
              // 更新当前行和光标位置
              currentLine.value = { page: prevPageIndex, line: prevLineIndex };
              cursorPosition.value = {
                page: prevPageIndex,
                line: prevLineIndex,
                noteIndex: prevLineEndIndex,
                visible: true
              };
              
              // 聚焦到上一页的最后一行
              const noteArea = getNoteAreaElement(prevPageIndex, prevLineIndex);
              if (noteArea) {
                noteArea.focus();
                activeNoteArea.value = noteArea;
              }
              
              // 保存历史记录
              saveHistory();
            }
          }
        } else if (event.key === 'Delete') {
          // 删除光标后的音符
          if (noteIndex < currentNotes.length - 1) {
            // 删除下一个音符
            pages.value[pageIndex].lines[lineIndex].notes.splice(noteIndex + 1, 1);
            
            // 光标位置不变
            
            // 保存历史记录
            saveHistory();
          } else if (noteIndex === currentNotes.length - 1 && 
                   (lineIndex < pages.value[pageIndex].lines.length - 1 || 
                    pageIndex < pages.value.length - 1)) {
            // 当前在行尾，需要合并下一行
            if (lineIndex < pages.value[pageIndex].lines.length - 1) {
              // 同一页中的下一行
              const nextLineIndex = lineIndex + 1;
              const nextLineNotes = pages.value[pageIndex].lines[nextLineIndex].notes;
              
              // 合并下一行到当前行
              pages.value[pageIndex].lines[lineIndex].notes = [
                ...currentNotes,
                ...nextLineNotes
              ];
              
              // 删除下一行
              pages.value[pageIndex].lines.splice(nextLineIndex, 1);
              
              // 光标位置不变
              
              // 保存历史记录
              saveHistory();
            } else if (pageIndex < pages.value.length - 1) {
              // 需要合并下一页的第一行
              const nextPageIndex = pageIndex + 1;
              const nextLineNotes = pages.value[nextPageIndex].lines[0].notes;
              
              // 合并下一页的第一行到当前行
              pages.value[pageIndex].lines[lineIndex].notes = [
                ...currentNotes,
                ...nextLineNotes
              ];
              
              // 如果下一页只有这一行，删除整个页面，否则只删除第一行
              if (pages.value[nextPageIndex].lines.length === 1) {
                pages.value.splice(nextPageIndex, 1);
              } else {
                pages.value[nextPageIndex].lines.splice(0, 1);
              }
              
              // 光标位置不变
              
              // 保存历史记录
              saveHistory();
            }
          }
        }
        
        // 重置光标闪烁
        resetCursorBlink();
        break;
        
      case 'Enter':
        // 插入新行
        event.preventDefault();
        
        // 获取当前行的音符
        const currentLineNotes = pages.value[pageIndex].lines[lineIndex].notes;
        let notesAfterCursor: MusicNote[] = [];
        
        // 如果光标不在行首，分割当前行
        if (noteIndex >= 0) {
          // 提取光标后的音符
          notesAfterCursor = currentLineNotes.splice(noteIndex + 1);
        }
        
        // 创建新行
        const newLineIndex = lineIndex + 1;
        
        // 插入新行，确保包含lyrics字段
        pages.value[pageIndex].lines.splice(newLineIndex, 0, { 
          notes: notesAfterCursor,
          lyrics: []
        });
        
        // 更新当前行和光标位置
        currentLine.value = { page: pageIndex, line: newLineIndex };
        cursorPosition.value = {
          page: pageIndex,
          line: newLineIndex,
          noteIndex: -1,
          visible: true
        };
        
        // 聚焦到新行
        nextTick(() => {
          const noteArea = getNoteAreaElement(pageIndex, newLineIndex);
          if (noteArea) {
            noteArea.focus();
            activeNoteArea.value = noteArea;
          }
        });
        
        // 保存历史记录
        saveHistory();
        break;
        
      case 'a':
        // 全选 (Ctrl+A)
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault();
          
          if (currentNotes.length > 0) {
            // 选择当前行的所有音符
            selection.value = {
              active: true,
              startPage: pageIndex,
              startLine: lineIndex,
              startNote: 0,
              endPage: pageIndex,
              endLine: lineIndex,
              endNote: currentNotes.length - 1
            };
          }
        }
        break;
        
      case 'c':
        // 复制 (Ctrl+C)
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault();
          handleCopy();
        }
        break;
        
      case 'v':
        // 粘贴 (Ctrl+V)
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault();
          handlePaste();
        }
        break;
        
      case 'x':
        // 剪切 (Ctrl+X)
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault();
          handleCut();
        }
        break;
        
      case 'z':
        // 撤销 (Ctrl+Z)
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault();
          undo();
        }
        break;
        
      case 'y':
        // 重做 (Ctrl+Y)
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault();
          redo();
        }
        break;
        
      default:
        // 其他键不做特殊处理
        break;
    }
    
    // 重置光标闪烁
    resetCursorBlink();
  };
  
  // 复制选中内容
  const copySelection = () => {
    // 调用处理复制的函数
    handleCopy();
  };
  
  // 从剪贴板粘贴
  const pasteFromClipboard = () => {
    // 调用处理粘贴的函数
    handlePaste();
  };
  
  // 导出简谱数据
  const exportScore = () => {
    return pages.value;
  };
  
  // 加载内容
  const loadContents = (data: any) => {
    if (data && Array.isArray(data)) {
      pages.value = data;
      saveHistory();
    }
  };
  
  // 保存内容
  const saveContents = () => {
    return JSON.stringify(pages.value);
  };
  
  // 清理定时器函数
  const cleanupTimers = () => {
    if (cursorBlinkInterval.value) {
      clearInterval(cursorBlinkInterval.value);
    }
  };
  
  // 在组件卸载前清理定时器
  onMounted(() => {
    window.addEventListener('beforeunload', cleanupTimers);
  });
  
  // 插入音符符号功能
  const insertNoteSymbol = (item: any) => {
    console.log('开始插入音符:', item.value);
    
    // 获取当前应该使用的音符区域的位置信息
    const { page, line } = currentLine.value;
  
    // 确保页面和行存在
    ensurePageAndLineExist(page, line);
  
    // 创建新的音符对象
    const newNote: MusicNote = {
      name: item.name || '',
      value: item.value,
      type: item.type,
      html: item.html || `<span class="music-symbol" data-note-type="${item.name}">${item.value}</span>`,
      id: generateUUID(),
      lyricIds: []
    };
    
    // 获取当前光标位置
    const noteIndex = cursorPosition.value.noteIndex;
    
    // 插入音符到数组中
    if (noteIndex === -1) {
      // 在行首插入
      pages.value[page].lines[line].notes.unshift(newNote);
      // 更新光标位置到新插入音符后
      cursorPosition.value.noteIndex = 0;
    } else if (noteIndex >= pages.value[page].lines[line].notes.length - 1) {
      // 在行末插入
      pages.value[page].lines[line].notes.push(newNote);
      // 更新光标位置到新插入音符后
      cursorPosition.value.noteIndex = pages.value[page].lines[line].notes.length - 1;
    } else {
      // 在音符中间插入
      pages.value[page].lines[line].notes.splice(noteIndex + 1, 0, newNote);
      // 更新光标位置
      cursorPosition.value.noteIndex = noteIndex + 1;
    }
    
    // 重置光标闪烁
    resetCursorBlink();
    
    // 聚焦到音符区域
    const noteArea = getNoteAreaElement(page, line);
    if (noteArea) {
      noteArea.focus();
      activeNoteArea.value = noteArea;
    }
    
    // 保存历史记录
    saveHistory();
  
    // 移除自动换行检查
    // checkAndAddNewLineIfFull(page, line);
  };
  
  // 检查并添加新行或页面（仅当行已满时）
  const checkAndAddNewLineIfFull = (pageIndex: number, lineIndex: number) => {
    // 获取当前行的音符数量
    const currentLineNotes = pages.value[pageIndex].lines[lineIndex];
    
    // 判断音符是否已经超过一定数量（可自定义阈值）
    const MAX_NOTES_PER_LINE = 20; // 每行最多20个音符
    if (currentLineNotes.notes.length >= MAX_NOTES_PER_LINE) {
      // 是否是页面的最后一行
      const isLastLine = lineIndex === pages.value[pageIndex].lines.length - 1;
  
      // 判断页面是否已满（行数达到上限）
      const MAX_LINES_PER_PAGE = 10; // 每页最多10行
      const isPageFull = pages.value[pageIndex].lines.length >= MAX_LINES_PER_PAGE;
  
      if (isLastLine && isPageFull) {
        // 页面已满，添加新页面
        pages.value.push({ 
          lines: [{ 
            notes: [],
            lyrics: []
          }]
        });
        
        // 切换到新页面
        nextTick(() => {
          currentLine.value = { page: pageIndex + 1, line: 0 };
          
          // 设置光标位置
          cursorPosition.value = {
            page: pageIndex + 1,
            line: 0,
            noteIndex: -1,
            visible: true
          };
  
          // 让新页面第一行获得焦点
          const newNoteArea = getNoteAreaElement(pageIndex + 1, 0);
          if (newNoteArea) {
            activeNoteArea.value = newNoteArea;
            newNoteArea.focus();
          }
        });
      } else {
        // 插入新行
        const newLineIndex = lineIndex + 1;
  
        // 检查新行是否需要创建
        if (newLineIndex >= pages.value[pageIndex].lines.length) {
          // 添加新行
          pages.value[pageIndex].lines.push({ 
            notes: [],
            lyrics: []
          });
        } else {
          // 在指定位置插入新行
          pages.value[pageIndex].lines.splice(newLineIndex, 0, { 
            notes: [],
            lyrics: []
          });
        }
  
        // 切换到新行
        nextTick(() => {
          currentLine.value = { page: pageIndex, line: newLineIndex };
          
          // 设置光标位置
          cursorPosition.value = {
            page: pageIndex,
            line: newLineIndex,
            noteIndex: -1,
            visible: true
          };
  
          // 让新行获得焦点
          const newNoteArea = getNoteAreaElement(pageIndex, newLineIndex);
          if (newNoteArea) {
            activeNoteArea.value = newNoteArea;
            newNoteArea.focus();
          }
        });
      }
  
      // 保存历史记录
      saveHistory();
    }
  };
  
  // 处理剪切操作
  const handleCut = () => {
    // 如果没有选中内容，不进行任何操作
    if (!selection.value.active) {
      console.log('没有选中内容，无法剪切');
      return;
    }
    
    // 先复制选中内容
    handleCopy();
    
    // 然后删除选中内容
    deleteSelectedNotes();
    
    console.log('剪切操作完成');
  };
  
  // 撤销操作
  const undo = () => {
    if (state.historyIndex > 0) {
      console.log('执行撤销操作，从索引', state.historyIndex, '到', state.historyIndex - 1);
      
      // 执行撤销
      state.historyIndex--;
      const editorState = JSON.parse(state.history[state.historyIndex]);
      
      // 更新页面数据
      pages.value = editorState;
      
      // 在DOM更新后设置光标位置
      nextTick(() => {
        // 设置光标到当前行的开始位置
        const { page, line } = currentLine.value;
        cursorPosition.value = {
          page,
          line,
          noteIndex: -1,
          visible: true
        };
        
        // 聚焦到音符区域
        const noteArea = getNoteAreaElement(page, line);
        if (noteArea) {
          noteArea.focus();
          activeNoteArea.value = noteArea;
        }
      });
    } else {
      console.log('已经是最早的历史记录，无法继续撤销');
    }
  };
  
  // 重做操作
  const redo = () => {
    if (state.historyIndex < state.history.length - 1) {
      console.log('执行重做操作，从索引', state.historyIndex, '到', state.historyIndex + 1);
      
      // 执行重做
      state.historyIndex++;
      const editorState = JSON.parse(state.history[state.historyIndex]);
      
      // 更新页面数据
      pages.value = editorState;
      
      // 在DOM更新后设置光标位置
      nextTick(() => {
        // 设置光标到当前行的开始位置
        const { page, line } = currentLine.value;
        cursorPosition.value = {
          page,
          line,
          noteIndex: -1,
          visible: true
        };
        
        // 聚焦到音符区域
        const noteArea = getNoteAreaElement(page, line);
        if (noteArea) {
          noteArea.focus();
          activeNoteArea.value = noteArea;
        }
      });
    } else {
      console.log('已经是最新的历史记录，无法继续重做');
    }
  };
  
  // 处理歌词输入获得焦点
  const handleLyricInputFocus = (event: FocusEvent, pageIndex: number, lineIndex: number) => {
    // 移除音符区域的焦点和活动状态
    const noteArea = getNoteAreaElement(pageIndex, lineIndex);
    if (noteArea) {
      noteArea.blur();
      
      // 保存当前光标位置，但不显示光标
      if (cursorPosition.value.page === pageIndex && cursorPosition.value.line === lineIndex) {
        cursorPosition.value.visible = false;
      }
    }
  };
  
  // 进入歌词编辑模式
  const enterLyricEditMode = (pageIndex: number, lineIndex: number) => {
    // 停止事件传播，防止触发音符区点击事件
    event?.stopPropagation();
    event?.preventDefault();
    
    // 设置当前正在编辑的歌词行
    lyricEditing.value = {
      page: pageIndex,
      line: lineIndex
    };
    
    // 如果音符区域当前有焦点，先取消焦点
    if (activeNoteArea.value) {
      activeNoteArea.value.blur();
    }
    
    // 在下一个DOM更新周期中聚焦到输入框
    nextTick(() => {
      if (lyricInputRef.value) {
        lyricInputRef.value.focus();
      }
    });
  };
  
  // 声明要暴露的函数和变量
  defineExpose({
    exportScore,
    undo,
    redo,
    saveContents,
    loadContents,
    insertNoteSymbol,
    addNewPage,
    addLyricLine,
    copySelection,
    pasteFromClipboard,
    handleNoteFocus,
    handleNoteBlur,
    handleNoteClick,
    handleKeyDown,
    onLyricInputBlur,
    onLyricInputKeydown,
    enterLyricEditMode,
    alignMode,
    setAlignMode
  });
  </script>
  
  <script lang="ts">
  export default {
    name: 'ScoreEditor',
  };
  </script>
  
  <style scoped>
  .editor-container {
    display: flex;
    width: 100%;
    height: 100%;
    max-height: 100%;
    overflow: hidden;
  }
  
  .editor-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    height: 100%;
    max-height: 100%;
    overflow: hidden;
  }
  
  .top-toolbar {
    display: flex;
    gap: 15px;
    padding: 8px 15px;
    background-color: #f0f0f0;
    border-bottom: 1px solid #ddd;
    z-index: 100;
    align-items: center;
    flex-shrink: 0;
  }
  
  .bottom-status-bar {
    padding: 6px 15px;
    background-color: #f0f0f0;
    border-top: 1px solid #ddd;
    z-index: 100;
    font-size: 12px;
    color: #666;
    flex-shrink: 0;
  }
  
  .zoom-info,
  .page-info {
    font-size: 13px;
    color: #555;
    margin: 0 5px;
  }
  
  .editor-scroll-container {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    background-color: #e0e0e0;
    padding: 20px;
    display: flex;
    justify-content: center;
  }
  
  .editor-zoom-container {
    transform-origin: top center;
    padding: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    height: fit-content;
  }
  
  /* 设置A4纸张尺寸 */
  .page-container {
    width: 210mm;  /* A4宽度 */
    min-height: 297mm; /* A4高度 */
    background-color: white;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
    margin-bottom: 20mm;
    position: relative;
    box-sizing: border-box;
    padding: 20px;
  }
  
  .line-container {
    display: flex;
    margin-bottom: 15px;
    align-items: stretch;
  }
  
  .note-area {
    flex: 1;
    min-height: 50px;
    border: 1px solid #ddd;
    padding: 10px;
    border-radius: 4px;
    outline: none;
    transition: border-color 0.2s;
    position: relative;
  }
  
  .note-area.active {
    border-color: #3498db;
    box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.3);
  }
  
  .note-area.no-text-input {
    cursor: default;
  }
  
  .note-area.no-text-input::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 0;
  }
  
  .notes-container {
    position: relative;
    min-height: 30px;
    font-family: 'MusicFont', sans-serif; /* 使用音符字体 */
    font-size: 24px;
    display: flex;
    flex-wrap: nowrap; /* 防止换行 */
    align-items: center;
    overflow-x: auto; /* 当内容溢出时显示水平滚动条 */
  }
  
  /* 左对齐模式（默认） */
  .notes-container {
    justify-content: flex-start;
  }
  
  /* 两端对齐模式 */
  .notes-container.notes-justify {
    justify-content: space-between;
  }
  
  /* 两端对齐且音符较多时，使用更紧凑的分布 */
  .notes-container.notes-justify:has(.note-span:nth-child(n+10)) {
    justify-content: space-evenly; /* 均匀分布 */
  }
  
  /* 两端对齐但音符不多时，避免过度拉伸 */
  .notes-container.notes-justify:has(.note-span:only-child),
  .notes-container.notes-justify:has(.note-span:nth-child(2):nth-last-child(1)),
  .notes-container.notes-justify:has(.note-span:nth-child(3):nth-last-child(1)) {
    justify-content: flex-start;
  }
  
  /* 增强音符与歌词的对应关系 */
  .notes-container.notes-justify + .lyric-container .lyric-display {
    display: flex;
    justify-content: space-between;
    padding-right: 28px; /* 为删除按钮留出空间 */
  }
  
  .notes-container:not(.notes-justify) + .lyric-container .lyric-display {
    text-align: left;
    text-align-last: left;
    justify-content: flex-start;
  }
  
  .empty-placeholder {
    color: #888;
    font-style: italic;
    user-select: none;
    pointer-events: none;
    width: 100%;
  }
  
  .note-span {
    display: inline-block;
    position: relative;
    font-family: 'MusicFont', sans-serif; /* 确保音符字体应用到单个音符 */
    margin: 0 2px;
    white-space: nowrap; /* 防止音符内部换行 */
    min-width: 1em; /* 保证最小宽度 */
  }
  
  /* 根据音符数量动态调整间距 */
  .notes-container:has(.note-span:nth-child(n+15)) .note-span {
    margin: 0 1px; /* 音符较多时减小间距 */
  }
  
  .notes-container:has(.note-span:nth-child(n+25)) .note-span {
    margin: 0; /* 音符非常多时移除间距 */
  }
  
  .note-span.selected {
    background-color: rgba(52, 152, 219, 0.2);
  }
  
  .virtual-cursor {
    display: inline-block;
    width: 2px;
    height: 20px;
    background-color: #3498db;
    vertical-align: middle;
    animation: blink 1s step-end infinite;
  }
  
  /* 歌词样式 */
  .lyric-container {
    margin-top: 10px;
    padding-top: 5px;
    border-top: 1px dashed #ddd;
    position: relative;
  }
  
  .lyric-display-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  
  /* 歌词两端对齐模式 */
  .lyric-display-container.lyric-justify .lyric-display {
    text-align: justify;
    text-align-last: justify;
    letter-spacing: 0.05em; /* 增加字间距，使文本更容易对齐 */
  }
  
  /* 歌词较短时避免过度拉伸 */
  .lyric-display-container.lyric-justify .lyric-display:empty,
  .lyric-display-container.lyric-justify .lyric-display:only-child {
    text-align: left;
    text-align-last: left;
  }
  
  .lyric-display {
    flex: 1;
    font-size: 16px;
    color: #555;
    min-height: 24px;
    padding: 4px;
    cursor: pointer;
    border-radius: 4px;
    transition: background-color 0.2s;
    white-space: pre; /* 保留空格，确保字符间距与编辑时一致 */
    position: relative; /* 用于精确定位歌词字符 */
    display: flex; /* 使用弹性布局 */
  }
  
  .lyric-display:hover {
    background-color: #f5f5f5;
  }
  
  .lyric-display:empty::before {
    content: '点击添加歌词';
    color: #aaa;
    font-style: italic;
  }
  
  .lyric-input-container {
    width: 100%;
  }
  
  .lyric-input {
    width: 100%;
    padding: 4px 8px;
    font-size: 16px;
    color: #555;
    border: 1px solid #3498db;
    border-radius: 4px;
    outline: none;
    box-sizing: border-box;
    white-space: pre; /* 保留空格，确保与显示模式一致 */
    font-family: inherit; /* 继承父元素字体 */
    min-height: 24px; /* 与显示模式保持一致 */
    background-color: rgba(255, 255, 255, 0.5); /* 半透明背景 */
  }
  
  .lyric-delete-btn {
    background: none;
    border: none;
    font-size: 16px;
    color: #999;
    cursor: pointer;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.2s, color 0.2s;
  }
  
  .lyric-delete-btn:hover {
    background-color: #ff4d4f;
    color: white;
  }
  
  @keyframes blink {
    from, to { opacity: 1; }
    50% { opacity: 0; }
  }
  
  /* 确保左侧菜单和右侧编辑区高度一致 */
  :deep(.make-score-container) {
    height: 100%;
    overflow-y: auto;
  }
  
  /* 当字符数量较多时，减小内部字符间距 */
  .notes-container:has(.note-span:nth-child(n+15)) + .lyric-container .lyric-display {
    letter-spacing: -0.05em;
  }
  
  /* 当字符数量非常多时，进一步减小内部字符间距 */
  .notes-container:has(.note-span:nth-child(n+25)) + .lyric-container .lyric-display {
    letter-spacing: -0.1em;
    font-size: 14px; /* 稍微减小字体大小 */
  }
  
  .justify-align {
    text-align: justify;
    text-align-last: justify;
  }
  
  .many-notes {
    letter-spacing: -0.05em;
  }
  
  .too-many-notes {
    letter-spacing: -0.1em;
    font-size: 14px; /* 稍微减小字体大小 */
  }
  
  /* 当音符数量与歌词字符数量不匹配时的处理 */
  .notes-container.notes-justify + .lyric-container .lyric-display {
    justify-content: space-between; /* 两端对齐与音符保持一致 */
  }
  
  /* 自动生成空白占位，使字符与音符数量对齐 */
  .notes-container.notes-justify + .lyric-container .lyric-display::after {
    content: "";
    flex: 0 0 auto; /* 不伸缩 */
    margin-right: 24px; /* 与删除按钮的宽度匹配 */
  }
  
  /* 编辑模式的输入框样式优化 */
  .lyric-input.justify-align {
    text-align: justify;
    text-align-last: justify;
    display: flex;
    letter-spacing: 0.05em; /* 默认字间距 */
    padding-right: 24px; /* 与删除按钮的宽度匹配 */
  }
  </style>
  
  